package com.heo.client;

import java.net.InetSocketAddress;

import org.apache.log4j.Logger;

import com.heo.protocol.packet.HeartReq;
import com.heo.protocol.packet.LoginReq;
import com.heo.server.SocketChannelMap;

import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleStateEvent;

/**
 * Created by zhangcf
 */
public class NettyClientHandler extends ChannelInboundHandlerAdapter
{
  private static Logger log = Logger.getLogger(NettyClientHandler.class);

  private int index = 0;

  private short times = 0;

  public NettyClientHandler(int index)
  {
    this.index = index;
  }

  public NettyClientHandler()
  {

  }

  @Override
  public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception
  {
    log.error(cause.getMessage(), cause);
    super.exceptionCaught(ctx, cause);
  }

  /***
   * 通道连接成功时触发
   */
  @Override
  public void channelActive(ChannelHandlerContext ctx) throws Exception
  {
    String channelId = ctx.channel().id().asShortText();
    String localIpAddress = ((InetSocketAddress) ctx.channel().localAddress()).getAddress().getHostAddress();
    log.info("[client][" + channelId + "][" + localIpAddress + "]连接创建成功。");

    String iemi = "1234567890abcde";
    short deviceType = 0x0001;
    short loginType = 0x00;
    String devicePass = "abcd";
    String firmwareVer = "1.00";
    String protocolVer = "1.00";
    LoginReq loginReq = null;
    try
    {
      loginReq = new LoginReq(iemi,loginType, deviceType, devicePass, firmwareVer, protocolVer);
      System.out.println(loginReq.toString());
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }

    ctx.writeAndFlush(loginReq).addListener(new ChannelFutureListener()
    {
      // 数据发送完毕后，触发本事件
      @Override
      public void operationComplete(ChannelFuture future) throws Exception
      {
        // future.channel().close().sync();//关闭连接
        log.debug("[client][" + channelId + "][" + localIpAddress + "]发送消息--->：[]成功。");
      }
    });

    // String msg = "aaaaaaaaaa";
    // ByteBuf encoded = ctx.alloc().buffer();
    // try
    // {
    // encoded.writeBytes(msg.getBytes());
    // ctx.writeAndFlush(encoded).addListener(new ChannelFutureListener()
    // {
    // // 数据发送完毕后，触发本事件
    // @Override
    // public void operationComplete(ChannelFuture future) throws Exception
    // {
    // // future.channel().close().sync();//关闭连接
    // log.debug("[client][" + channelId + "]发送消息：[" + msg + "]成功。本地IP：" +
    // localIpAddress);
    // }
    // });
    // }
    // catch (Exception e)
    // {
    // log.error(e.getMessage(), e);
    // throw e;
    // }
    // finally
    // {
    // // ReferenceCountUtil.release(encoded);
    // }
  }

  /**
   * 收到服务端发过来的数据时触发
   */
  @Override
  public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception
  {
    String channelId = ctx.channel().id().asShortText();
    String localIpAddress = ((InetSocketAddress) ctx.channel().localAddress()).getAddress().getHostAddress();

    log.debug("[client][" + channelId + "][" + localIpAddress + "]<---收到消息：[" + msg.toString() + "]");

    if (index >= 50)
    {
      return;
    }

    HeartReq heartReq = new HeartReq(channelId);
    ctx.writeAndFlush(heartReq).addListener(new ChannelFutureListener()
    {
      // 数据发送完毕后，触发本事件
      @Override
      public void operationComplete(ChannelFuture future) throws Exception
      {
        // future.channel().close().sync();//关闭连接
        log.debug("[client][" + channelId + "][" + localIpAddress + "]发送消息--->成功。");
      }
    });
    
    index++;

    // String sendStr = "xxxxxxxxxx";
    // ByteBuf sendBuf = ctx.alloc().buffer();
    // sendBuf.writeBytes(sendStr.getBytes());
    // // 非阻塞方式，在发送完数据以后，触发发送完毕的事件
    // log.debug("[client][" + channelId + "][" + localIpAddress +
    // "]正在向服务端发送消息：[" + sendStr + "]");
    // ctx.pipeline().writeAndFlush(sendBuf).addListener(new
    // ChannelFutureListener()
    // {
    // // 数据发送完毕后，触发本事件
    // @Override
    // public void operationComplete(ChannelFuture future) throws Exception
    // {
    // log.debug("[client][" + channelId + "]向服务端发送消息：[" + sendStr + "]完成。");
    // }
    // });

    // ByteBuf in = (ByteBuf) msg;
    // try
    // {
    // if (in.isReadable())
    // {
    // String str = in.toString(CharsetUtil.US_ASCII);
    // log.debug("[client][" + channelId + "][" + localIpAddress + "]收到服务端消息：["
    // + str + "]");
    // Thread.sleep(100);
    // String sendStr = "xxxxxxxxxx";
    // ByteBuf sendBuf = ctx.alloc().buffer();
    // sendBuf.writeBytes(sendStr.getBytes());
    // // 非阻塞方式，在发送完数据以后，触发发送完毕的事件
    // log.debug("[client][" + channelId + "][" + localIpAddress +
    // "]正在向服务端发送消息：[" + sendStr + "]");
    // ctx.pipeline().writeAndFlush(sendBuf).addListener(new
    // ChannelFutureListener()
    // {
    // // 数据发送完毕后，触发本事件
    // @Override
    // public void operationComplete(ChannelFuture future) throws Exception
    // {
    // log.debug("[client][" + channelId + "]向服务端发送消息：[" + sendStr + "]完成。");
    // }
    // });
    // }
    // }
    // finally
    // {
    // ReferenceCountUtil.release(msg);
    // }
  }

  /***
   * 通道断开时触发
   */
  @Override
  public void channelInactive(ChannelHandlerContext ctx) throws Exception
  {
    String channelId = ctx.channel().id().asShortText();
    String localIpAddress = ((InetSocketAddress) ctx.channel().localAddress()).getAddress().getHostAddress();

    SocketChannelMap.remove(channelId);
    log.info("[client][" + channelId + "][" + localIpAddress + "]连接已关闭。");
  }

  @Override
  public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception
  {
    if (evt instanceof IdleStateEvent)
    {
      String channelId = ctx.channel().id().asShortText();
      String localIpAddress = ((InetSocketAddress) ctx.channel().localAddress()).getAddress().getHostAddress();

      IdleStateEvent e = (IdleStateEvent) evt;
      // 断开连接
      ctx.channel().close().sync();
      switch (e.state())
      {
        case READER_IDLE:
          log.info("[client][" + channelId + "][" + localIpAddress + "]" + "读取网络连接超时，连接已断开。");
          break;
        case WRITER_IDLE:
          log.info("[client][" + channelId + "][" + localIpAddress + "]" + "写入网络连接超时，连接已断开。");
          break;
        case ALL_IDLE:
          log.info("[client][" + channelId + "][" + localIpAddress + "]" + "读写网络连接超时，连接已断开。");
          break;
        default:
          break;
      }
    }
  }
}
